﻿using MinimalistFoodStreet.BackEnd.Infrastructure.EFCore;
using MinimalistFoodStreet.BackEnd.Server.IServer;
using System;

namespace JoyfulHomeJourney.BackEnd.Api.Admin.MiddleWares
{
    /// <summary>
    /// 全局错误处理中间件
    /// </summary>
    public class GlobalErrorHandler
    {
        private readonly RequestDelegate _next;
        private readonly IConfiguration _configuration;

        /// <summary>
        /// 依赖注入所需参数，next，configuration
        /// </summary>
        /// <param name="next"></param>
        /// <param name="configuration"></param>
        public GlobalErrorHandler(RequestDelegate next, IConfiguration configuration)
        {
            _next = next;
            _configuration = configuration;
        }

        /// <summary>
        /// 调用,依赖注入所需参数，context,logServer
        /// </summary>
        /// <param name="context"></param>
        /// <param name="logServer"></param>
        /// <returns></returns>
        public async Task InvokeAsync(HttpContext context, ILogServer logServer)
        {
            try
            {
                await _next(context);
            }
            catch (Exception ex)
            {
                try
                {
                    // 错误记录时间
                    DateTime now = DateTime.Now;
                    // 获取请求参数
                    string requestParames = "";
                    foreach (var key in context.Request.Query.Keys)
                    {
                        requestParames += key + "=" + context.Request.Query[key] + "&";
                    }

                    // 如果需要获取表单数据或 JSON 数据
                    if (context.Request.HasFormContentType)
                    {
                        var formCollection = context.Request.Form;
                        // 使用 formCollection 获取表单数据
                        foreach (var key in formCollection.Keys)
                        {
                            requestParames += key + "=" + formCollection[key] + "&";
                        }
                    }
                    else if (context.Request.ContentType?.StartsWith("application/json")??false)
                    {
                        // 读取 JSON 请求体
                        var requestBody = context.Request.Body;
                        requestBody.Position = 0;
                        using (var reader = new StreamReader(requestBody))
                        {
                            var bodyText = await reader.ReadToEndAsync();
                            requestParames += bodyText;
                        }
                    }
                    string url = context.Request.Scheme + "://" + context.Request.Host + context.Request.Path;
                    // 写入数据库
                    try
                    {
                        logServer.AddErrorLog(new ErrorLog
                        {
                            ElParams = requestParames,
                            ElErrorTime = now,
                            ElMessage = ex.Message,
                            ElUrl = url,
                            ElStackTrack = ex.StackTrace??""
                        });
                    }
                    catch
                    {

                    }

                    // 写入本地文件 结构类似于 2022-10-11/12.txt
                    try
                    {
                        string nowDirectoryPath = Path.Combine(_configuration["LogBasePaths:Error"]!, now.ToString("yyyy-MM-dd"));
                        if (!Directory.Exists(nowDirectoryPath))
                        {
                            Directory.CreateDirectory(nowDirectoryPath);
                        }
                        string nowFilePath = Path.Combine(nowDirectoryPath, now.ToString("HH"), ".txt");
                        if (!File.Exists(nowFilePath))
                        {
                            File.Create(nowFilePath);
                        }
                        List<string> stringLines = new List<string>();
                        stringLines.Add($"message:{ex.Message}");
                        stringLines.Add($"stackTrace:{ex.StackTrace}");
                        stringLines.Add($"url:{url}");
                        stringLines.Add($"params:{requestParames}");
                        stringLines.Add($"datetime:{now:yyyy-MM-dd HH:mm:ss}");

                        _ = File.AppendAllTextAsync(nowFilePath, string.Join("\n", stringLines));
                    }
                    catch
                    {

                    }

                    context.Response.StatusCode = 500;
                    context.Response.ContentType = "text/plain; charset=utf-8";
                    await context.Response.WriteAsync(ex.Message);
                }
                catch
                {

                }
            }
        }
    }
}
